﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using SharpPopulatorLib;

namespace SharpPopulator
{

    public partial class Populator : Form 
    {

    #region Atributes

        private SharpPopulatorLib.Populator _Populator;
        private List<DBField> fields;
        private ConfiguredFieldCollection _ConfiguratedFieldCollection;
        private ConfiguredField _ConfiguredField;

    #endregion

    #region Constructor
    
        public Populator(List<String> tables) 
        {
            InitializeComponent();
            lboxTables.DataSource = tables;
            //cboxTables.DataSource = tables;
            _ConfiguratedFieldCollection = new ConfiguredFieldCollection();
        }

    #endregion

    #region Events

        //private void lboxTables_DoubleClick(object sender, EventArgs e)
        //{
        //    //
        //    //MessageBox.Show(lboxTables.SelectedItem.ToString());
        //    fields = new List<DBField>();
        //    fields = DBManager.GetFields(lboxTables.SelectedItem.ToString(), Settings.ConnectionString);

        //    lboxFields.Items.Clear();
        //    foreach (DBField field in fields)
        //    { lboxFields.Items.Add(field.Name); }

        //    //dgvFields.Rows.Clear();
        //    //foreach (DBField field in fields)
        //    //{ dgvFields.Rows.Add(field.Name, field.IsNullable, field.DataType, field.CharacterLenght, field.NumericPrecision); }
        //}

        private void Populator_Load(object sender, EventArgs e)
        {
            //
            _Populator = new SharpPopulatorLib.Populator();
        }

        private void tsbGenerate_Click(object sender, EventArgs e)
        {
            _Populator.ConfiguredFields = _ConfiguratedFieldCollection;
            _Populator.NumberOfRecords = Convert.ToInt32(nudRecords.Value);
            _Populator.Populate();
            
            // FRA
            // Here read the values in dgvConfigure and proceed with
            // reading data sources, preparing and injectign the sql
        }

        /// <summary>
        /// To add a new row with fields data and definition
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //private void btnConfigure_Click(object sender, EventArgs e)
        //{
        //    // FRA
        //    // This method illustrated how to present the configuration options to user
        //    // based on the following table schema with two fields:  id int, fullName nvarchar(50)

        //    dgvConfigure.Rows.Clear(); // <-- for some reason the fucking grid adds an additional row (empty), we need to get rid of it!!

        //    if (fields != null)
        //    {
        //        foreach (DBField field in fields)
        //        {
        //            DataGridViewRow row = new DataGridViewRow();
        //            DataGridViewTextBoxCell f = new DataGridViewTextBoxCell();
        //            ConfiguredField _ConfiguredField = new ConfiguredField();

        //            f.Value = field.Name;
        //            row.Cells.Add(f);

        //            f = new DataGridViewTextBoxCell();
        //            f.Value = field.DataType;
        //            row.Cells.Add(f);
                    
        //            switch (field.DataType)
        //            {
        //                case "int":
        //                {
        //                    // FRA
        //                    // here validate if int is auto_increment, this info should come from DBManager.GetFields()
        //                    // if auto_increment, disable column so user can not mess with values
        //                    f = new DataGridViewTextBoxCell();
        //                    f.Value = 0;
        //                    row.Cells.Add(f);
        //                }
        //                break;
        //                case "smallint":
        //                {
        //                    f = new DataGridViewTextBoxCell();
        //                    f.Value = 0;
        //                    row.Cells.Add(f);
        //                }
        //                break;
        //                case "varchar":
        //                {
        //                    DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
        //                    foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
        //                    { comboCell.Items.Add(s); }
        //                    if (comboCell.Items.Contains(field.Name.ToUpper()))
        //                    { comboCell.Value = field.Name.ToUpper(); }
        //                    row.Cells.Add(comboCell);
        //                }
        //                break;
        //                case "nvarchar":
        //                {
        //                    DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
        //                    foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
        //                    { comboCell.Items.Add(s); }
        //                    if (comboCell.Items.Contains(field.Name.ToUpper()))
        //                    { comboCell.Value = field.Name.ToUpper(); }
        //                    row.Cells.Add(comboCell);
        //                }
        //                break;
        //                case "date":
        //                {
        //                    f = new DataGridViewTextBoxCell();
        //                    f.Value = DateTime.Now.ToShortDateString();
        //                    row.Cells.Add(f);
        //                }
        //                break;
        //                case "text":
        //                {
        //                    DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
        //                    foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
        //                    { comboCell.Items.Add(s); }
        //                    if (comboCell.Items.Contains(field.Name.ToUpper()))
        //                    { comboCell.Value = field.Name.ToUpper(); }
        //                    row.Cells.Add(comboCell);
        //                }
        //                break;
        //            }
        //            dgvConfigure.Rows.Add(row);
        //        }
        //    }
        //}

        private void tsbClose_Click(object sender, EventArgs e)
        {
            //To close this form
            this.Close();
        }

        //private void cboxTables_TextChanged(object sender, EventArgs e)
        //{
        //    //To get the collection of fields
        //    fields = new List<DBField>();
        //    fields = DBManager.GetFields(cboxTables.Text, Settings.ConnectionString);

        //    lboxTables.Items.Clear();
        //    foreach (DBField field in fields)
        //    { lboxTables.Items.Add(field.Name); }
        //}

        private void dgvConfigure_SelectionChanged(object sender, EventArgs e)
        {
            ////
            //switch (dgvConfigure["DataType", dgvConfigure.CurrentRow.Index].Value.ToString())
            //{
            //    case "int":
            //    {
            //        IntProperties _IntProp = new IntProperties();
            //        //pgFieldConfiguration.SelectedObject = _IntProp;
            //    }
            //    break;
            //    case "smallint":
            //    {
            //        IntProperties _IntProp = new IntProperties();
            //        //pgFieldConfiguration.SelectedObject = _IntProp;
            //    }
            //    break;
            //    case "nvarchar":
            //    {
            //        if (dgvConfigure.CurrentRow.Cells["TypeOf"].Value != null)
            //        { StringExpression((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), dgvConfigure.CurrentRow.Cells["TypeOf"].Value.ToString())); }
            //        else
            //        { //pgFieldConfiguration.SelectedObject = null; 
            //        }
            //    }
            //    break;
            //    case "varchar":
            //    {
            //        if (dgvConfigure.CurrentRow.Cells["TypeOf"].Value != null)
            //        { StringExpression((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), dgvConfigure.CurrentRow.Cells["TypeOf"].Value.ToString())); }
            //        else
            //        { //pgFieldConfiguration.SelectedObject = null; 
            //        }
            //    }
            //    break;
            //    case "date":
            //    {
            //        DateProperties _DateProp = new DateProperties();
            //        _DateProp.Date = DateTime.Now;
            //        //pgFieldConfiguration.SelectedObject = _DateProp;
            //    }
            //    break;
            //}
        }

        private void btnDiscard_Click(object sender, EventArgs e)
        {
            //
            dsConfigure.Visible = false;
        }

        private void lboxTables_SelectedValueChanged(object sender, EventArgs e)
        {
            // FRA
            // This method illustrated how to present the configuration options to user
            // based on the following table schema with two fields:  id int, fullName nvarchar(50)

            fields = new List<DBField>();
            fields = DBManager.GetFields(lboxTables.Text, Settings.ConnectionString, true);

            dgvConfigure.Rows.Clear(); // <-- for some reason the fucking grid adds an additional row (empty), we need to get rid of it!!

            if (fields != null)
            {
                foreach (DBField field in fields)
                {
                    DataGridViewRow row = new DataGridViewRow();
                    DataGridViewTextBoxCell f = new DataGridViewTextBoxCell();
                    ConfiguredField _ConfiguredField = new ConfiguredField();

                    f.Value = field.Name;
                    row.Cells.Add(f);

                    f = new DataGridViewTextBoxCell();
                    f.Value = field.DataType;
                    row.Cells.Add(f);

                    switch (field.DataType)
                    {
                        case "int":
                            {
                                // FRA
                                // here validate if int is auto_increment, this info should come from DBManager.GetFields()
                                // if auto_increment, disable column so user can not mess with values
                                f = new DataGridViewTextBoxCell();
                                f.Value = 0;
                                row.Cells.Add(f);
                            }
                            break;
                        case "smallint":
                            {
                                f = new DataGridViewTextBoxCell();
                                f.Value = 0;
                                row.Cells.Add(f);
                            }
                            break;
                        case "varchar":
                            {
                                DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
                                foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
                                { comboCell.Items.Add(s); }
                                if (comboCell.Items.Contains(field.Name.ToUpper()))
                                { comboCell.Value = field.Name.ToUpper(); }
                                row.Cells.Add(comboCell);
                            }
                            break;
                        case "nvarchar":
                            {
                                DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
                                foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
                                { comboCell.Items.Add(s); }
                                if (comboCell.Items.Contains(field.Name.ToUpper()))
                                { comboCell.Value = field.Name.ToUpper(); }
                                row.Cells.Add(comboCell);
                            }
                            break;
                        case "date":
                            {
                                f = new DataGridViewTextBoxCell();
                                f.Value = DateTime.Now.ToShortDateString();
                                row.Cells.Add(f);
                            }
                            break;
                        case "text":
                            {
                                DataGridViewComboBoxCell comboCell = new DataGridViewComboBoxCell();
                                foreach (string s in Enum.GetNames(typeof(StringsExpressionsType)))
                                { comboCell.Items.Add(s); }
                                if (comboCell.Items.Contains(field.Name.ToUpper()))
                                { comboCell.Value = field.Name.ToUpper(); }
                                row.Cells.Add(comboCell);
                            }
                            break;
                    }
                    dgvConfigure.Rows.Add(row);
                }
            }
        }

        //private void dgvConfigure_CellContentClick(object sender, DataGridViewCellEventArgs e)
        //{
        //    //
        //    tbFieldName.Text = dgvConfigure.Rows[e.RowIndex].Cells["Field"].Value.ToString();
        //    _ConfiguredField = _ConfiguratedFieldCollection[tbFieldName.Text.ToString()];
        //    switch (dgvConfigure["DataType", dgvConfigure.CurrentRow.Index].Value.ToString())
        //    {
        //        case "int":
        //        {
                    
        //            if (_ConfiguredField != null)
        //            { pgFieldConfiguration.SelectedObject = _ConfiguredField.Configuration; }
        //            else
        //            {  
        //                IntProperties _IntProp = new IntProperties();
        //                _IntProp.End = _IntProp.Start + Convert.ToInt32(nudRecords.Value);
        //                pgFieldConfiguration.SelectedObject = _IntProp;
        //            }
        //        }
        //        break;
        //        case "smallint":
        //        {
        //            if (_ConfiguredField != null)
        //            { pgFieldConfiguration.SelectedObject = _ConfiguredField.Configuration; }
        //            else
        //            {
        //                IntProperties _IntProp = new IntProperties();
        //                _IntProp.End = _IntProp.Start + Convert.ToInt32(nudRecords.Value);
        //                pgFieldConfiguration.SelectedObject = _IntProp;
        //            }
        //        }
        //        break;
        //        case "nvarchar":
        //        {
        //            if (_ConfiguredField != null)
        //            { pgFieldConfiguration.SelectedObject = _ConfiguredField.Configuration; }
        //            else
        //            {
        //                StringProperties _StringProperties = new StringProperties();
        //                pgFieldConfiguration.SelectedObject = _StringProperties;
        //            }
        //        }
        //        break;
        //        case "varchar":
        //        {
        //            if (_ConfiguredField != null)
        //            { pgFieldConfiguration.SelectedObject = _ConfiguredField.Configuration; }
        //            else
        //            {
        //                if (dgvConfigure["TypeOf", dgvConfigure.CurrentRow.Index].Value.ToString() == "EMail")
        //                {
        //                    DomainProperties _DomainProp = new DomainProperties();
        //                    pgFieldConfiguration.SelectedObject = _DomainProp;
        //                }
        //                else
        //                { 
        //                    StringProperties _StringProperties = new StringProperties();
        //                    pgFieldConfiguration.SelectedObject = _StringProperties;
        //                }
                        
        //            }
        //        }
        //        break;
        //        case "date":
        //        {
        //            if (_ConfiguredField != null)
        //            { pgFieldConfiguration.SelectedObject = _ConfiguredField.Configuration; }
        //            else
        //            {
        //                DateProperties _DateProp = new DateProperties();
        //                _DateProp.Date = DateTime.Now;
        //                pgFieldConfiguration.SelectedObject = _DateProp;
        //            }
        //        }
        //        break;
        //    }
        //    dsConfigure.Visible = true;
        //}

        private void btnKeep_Click(object sender, EventArgs e)
        {
            //
            if (_ConfiguredField != null)
            { 
                _ConfiguratedFieldCollection[tbFieldName.Text.ToString()].Configuration = pgFieldConfiguration.SelectedObject;
                dsConfigure.Visible = false;
            }
            else
            {
                ConfigurationPropertiesType _PropertiesType = GetPropertiesType();
                //_ConfiguratedFieldCollection.Add(tbFieldName.Text.ToString(), pgFieldConfiguration.SelectedObject, _PropertiesType);
                dgvConfigure.Rows[dgvConfigure.CurrentRow.Index].Cells[3].Value = true;
                dsConfigure.Visible = false;
            }
            _ConfiguredField = null;
        }

    #endregion
               
    #region Private methods

        //private void StringExpression(StringsExpressionsType Expression)
        //{
        //    //To determine the StringProperty to configure
        //    switch (Expression)
        //    {
        //        case StringsExpressionsType.TEXT:
        //        {
        //            StringProperties _StringProperties = new StringProperties();
        //            _StringProperties.ExpressionType = StringsExpressionsType.TEXT;
        //            pgFieldConfiguration.SelectedObject = _StringProperties;
        //        }
        //        break;
        //        case StringsExpressionsType.EMAIL:
        //        {
        //            DomainProperties _DomainProperties = new DomainProperties();
        //            pgFieldConfiguration.SelectedObject = _DomainProperties;
        //        }
        //        break;
        //        case StringsExpressionsType.FULLNAME:
        //        {
        //            StringProperties _StringProperties = new StringProperties();
        //            _StringProperties.ExpressionType = StringsExpressionsType.FULLNAME;
        //            pgFieldConfiguration.SelectedObject = _StringProperties;
        //        }
        //        break;
        //        case StringsExpressionsType.LASTNAME:
        //        {
        //            StringProperties _StringProperties = new StringProperties();
        //            _StringProperties.ExpressionType = StringsExpressionsType.LASTNAME;
        //            pgFieldConfiguration.SelectedObject = _StringProperties;
        //        }
        //        break;
        //        case StringsExpressionsType.NAME:
        //        {
        //            StringProperties _StringProperties = new StringProperties();
        //            _StringProperties.ExpressionType = StringsExpressionsType.NAME;
        //            pgFieldConfiguration.SelectedObject = _StringProperties;
        //        }
        //        break;
        //        case StringsExpressionsType.PASSWORD:
        //        {
        //            EncriptationProperties _EncriptationProperties = new EncriptationProperties();
        //            pgFieldConfiguration.SelectedObject = _EncriptationProperties;
        //        }
        //        break;
        //        default:
        //        { pgFieldConfiguration.SelectedObject = null; }
        //        break;
        //    }

        //}

        private ConfigurationPropertiesType GetPropertiesType()
        { 
            //
            switch (dgvConfigure["DataType", dgvConfigure.CurrentRow.Index].Value.ToString())
            {
                case "int":
                { return ConfigurationPropertiesType.Int; }
                case "smallint":
                { return ConfigurationPropertiesType.Int; }
                case "nvarchar":
                { return GetStringProperties(); }
                case "varchar":
                { return GetStringProperties(); }
                case "date":
                { return ConfigurationPropertiesType.Date; }
                default:
                { return ConfigurationPropertiesType.String; }
            }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private ConfigurationPropertiesType GetStringProperties()
        {
            //
            switch((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), dgvConfigure.CurrentRow.Cells["TypeOf"].Value.ToString()))
            {
                case StringsExpressionsType.TEXT:
                { return ConfigurationPropertiesType.String; }
                case StringsExpressionsType.EMAIL:
                { return ConfigurationPropertiesType.Domain; }
                case StringsExpressionsType.FULLNAME:
                { return ConfigurationPropertiesType.String; }
                case StringsExpressionsType.LASTNAME:
                { return ConfigurationPropertiesType.String; }
                case StringsExpressionsType.NAME:
                { return ConfigurationPropertiesType.String; }
                case StringsExpressionsType.PASSWORD:
                { return ConfigurationPropertiesType.Encriptation; }
                default:
                { return ConfigurationPropertiesType.String; }
            }
        }
        
    #endregion

        private void lboxTables_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

    }

}
